<?php

namespace app\manual\controller;

use think\Config;
use think\Cache;
use think\Db;

class Doc extends Base
{

    public function index($type = 3)
    {
        $types = [
            3 => ['name'=>'乘客','dir' => '/controller/passenger','mk'=>'api'],
            2 => ['name'=>'司机','dir' => '/controller/driver','mk'=>'api'],
            4 => ['name'=>'管理端','dir' => '', 'mk' => 'adminapi/controller'],
            5 => ['name'=>'开放平台','dir' => '', 'mk' => 'open/controller'],
//            5 => ['name'=>'第三方','dir' => '', 'mk' => 'open/controller'],
        ];

        $current = $types[$type];
        $dir = $current['dir'];
        $mk = $current['mk'];

        //搜索
        $keyword = input('param.keyword');
        $keyword = preg_replace('/\s+/','.*',$keyword);

        $arr =  $this->getDoc($dir, $mk, $keyword);
        asort($arr);

        $this->assign('tree',$arr);
        $this->assign('types',$types);
        $this->assign('current',$current);

        return $this->fetch('index');
    }

    public function getDoc($dir, $mk, $keyword = '')
    {
        $moudule    = $mk;
        $controller = $dir;
        $conArr     = explode('/', $controller);
        $arr        = new \DirectoryIterator(APP_PATH . $moudule . $controller);
        $brr        = [];
        $module_id  = 2;
        $user_id    = 1;
        foreach ($arr as $tt) {
            if ($arr->isDot()) {
                continue;
            }
            if ($arr->isDir()) {
                continue;
            }
            $serviceName = $tt->getBasename('.php');
            if($serviceName!='Test'){
//                continue;
            }
            $controllerStr = str_replace('/', '\\', $moudule . $controller) . "\\";
            $rc = new \ReflectionClass("app\\" . $controllerStr . $serviceName);
            $comment = $rc->getDocComment();
            preg_match("/@name【(.*?)】/", $comment, $out);
            if (empty($out[1])) {
                continue;
            }
            $classname = $out[1];
            $brr[$serviceName]['name'] = $classname;#名字

            preg_match("/@baseurl【(.*?)】/", $comment, $out);
            $baseurl = $out[1];
            preg_match("/@file【(.*?)】/", $comment, $out);
            $file = $out[1];
            $methods = $rc->getMethods();
            foreach ($methods as $m) {
                $data = [];
                if ($m->class == "app\\" . $controllerStr . $serviceName) {
                    $bz = $m->getDocComment();
                    $bz = preg_replace('/\r\s+\*?/', '', $bz);
                    $bz = str_replace([ "\r", "\n", "\r\n", ' '], '', $bz);
                    preg_match("/@name【(.*?)】/", $bz, $out);
                    $data['title'] = $out[1];
                    if (empty($out[1])) {
                        continue;
                    }
                    //对应数据表
                    preg_match("/@table【(.*?)】/", $bz, $out);
                    $table = $out[1];
                    $data['table'] = $table;
                    $data['module_id'] = $module_id;
                    $data['user_id'] = $user_id;
                    preg_match("/@desc【(.*?)】/", $bz, $out);
                    $data['intro'] = $out[1];
                    preg_match("/@uri【(.*?)】/", $bz, $out);
                    $requestUrl   = $baseurl . "/" . $out[1];
                    $data['uri']  = isset($out[1]) && !empty($out[1]) ? $requestUrl : str_replace(['\\','app/','/controller'],['/'],$m->class) . "/" . $m->name;
                    $data['func'] = $m->name;
                    $data['file'] = $file;
                    preg_match("/@method【(.*?)】/", $bz, $out);
                    $data['method'] = $out[1];
                    preg_match("/@param【(.*?)】/", $bz, $out);
                    $param = $out[1];

                    //替换通用
                    $param = str_replace(['_list','_delete'],['fields$string$*$字段名称#where_json$json$$查询条件#is_all$int$0$是否返回全部#with_trashed$int$0$0未删除1包含删除2只含删除#page$int$1$页数#pagenum$int$20$记录数','ids $ int $ 1,2 $ 要删除的ID（多个,隔开） #'],$param);

                    //无参数关联数据表
                    if(!$param && $table) {
                        preg_match("/@except【(.*?)】/", $bz, $out);
                        $except = array_filter(explode(',',$out[1]));
                        preg_match("/@allow【(.*?)】/", $bz, $out);
                        $allow = array_filter(explode(',',$out[1]));

                        $fields = reset($this->getTable($table));

                        foreach($fields AS $key => $field) {
                            in_array('PK',$except) && $field['COLUMN_KEY'] == 'PRI' && $except[] = $key;
                            if($except && in_array($key,$except) || $allow && !in_array($key,$allow) || in_array($key,['delete_time','create_time','update_time']))
                            {
                                continue;
                            }
                            $p11['name'] = $key;
                            $p11['title'] = $field['COLUMN_COMMENT'];
                            $p11['type'] = $field['COLUMN_TYPE'];
                            $p11['default_value'] = $field['COLUMN_DEFAULT'];
                            $p11['is_required'] = $field['IS_NULLABLE'] == 'NO' && is_null($field['COLUMN_DEFAULT']) ? 1 : 0;
                            $data['param'][] = $p11;
                        }
//                        halt($data);
                    } else {
                        $paramArr = explode('#', $param);
                        foreach ($paramArr as $p1) {
                            $p1Arr = explode('$', $p1);
                            $p11 = [];
                            if(empty($p1Arr[0])) continue;
                            $p11['name']  = str_replace('@','',$p1Arr[0]);
                            $atCount      = substr_count($p1Arr[0],'@');
                            $p11['count'] = $atCount;
                            $p11['len']   = 4 - $atCount;
                            $p11['title'] = $p1Arr[3];
                            $p11['type']  = $p1Arr[1];
                            $p11['default_value'] = $p1Arr[2];
//                            $p11['button']        = strlen($p11['default_value']) > 20 ? 1 : 0;
                            $p11['is_required'] = isset($p1Arr[4]) ? 1 : 0;
                            $p11['method'] = 1;
                            $p11['user_id'] = $user_id;
                            $data['param'][] = $p11;
                        }
                    }
                    //返回值说明
                    preg_match("/@return【(.*?)】/", $bz, $out);
                    $param = $out[1] ?: "* code $ int $ number|1-1 $ 标识1-成功 0-失败#* msg $ string $  $ code=0，错误信息#* count $ int $ 100 $ 结果总数 #* data $ json $ $ 数据列表 #* description $ json $ $ 接口说明";
                    $paramArr = explode('#', $param);
                    foreach ($paramArr as $p1) {
                        $p1Arr                = explode('$', $p1);
                        $p11                  = [];
                        if(empty($p1Arr[0])) continue;
                        $p11['name']  = str_replace('@','',$p1Arr[0]);
                        $atCount      = substr_count($p1Arr[0],'@');
                        $p11['count'] = $atCount;
                        $p11['len']   = 4 - $atCount;
                        $p11['title']         = $p1Arr[3];
                        $p11['type']          = $p1Arr[1];
                        $p11['mock']          = $p1Arr[2];
                        $p11['default_value'] = $p1Arr[4];
                        $p11['button']        = strlen($p1Arr[4]) > 20 ? 1 : 0;
                        $p11['is_required']   = 0;
                        $p11['method']        = 2;
                        $p11['user_id']       = $user_id;
                        $data['return'][]     = $p11;
                    }
                    //搜索
                    if($keyword)
                    {
                        $rslt = [];
                        foreach ($data AS $key=>$val) {
                            $rslt[] = preg_match("/{$keyword}/i",$val,$match) ;
                        }
                        if(!max($rslt)) {
                            $data = [];
                        }
                    }


                }
                if (!empty($data)) {
                    $brr[$serviceName]['data'][] = $data;
                }
            }
            if(!$brr[$serviceName]['data']) {
                $brr[$serviceName] = [];
            }
        }
        return array_filter($brr);
    }

    public function data()
    {
        //缓存
        $tables = Cache::remember('manual_tabels',function(){
            $dbserver   = Config::get('database.hostname');
            $dbusername = Config::get('database.username');
            $dbpassword = Config::get('database.password');
            $database   = Config::get('database.database');
            $con        = new \mysqli($dbserver, $dbusername, $dbpassword, $database);
            $rs         = $con->query('show tables');
            $tables     = [];
            $tablesKey = 'Tables_in_' . $database;
            foreach ($rs as $key => $value) {
                $temp = [];
                $sql = 'SELECT * FROM ';
                $sql .= 'INFORMATION_SCHEMA.TABLES ';
                $sql .= 'WHERE ';
                $sql .= "table_name = '" . $value[ $tablesKey ] . "'  AND table_schema = '$database'";
                $rs2 = $con->query($sql);
                foreach ($rs2 as $key2 => $value2) {
                    $temp['func'] = $value2['TABLE_NAME'];
                    $temp['title'] = $value2['TABLE_COMMENT'] ?: $temp['func'];
                }
                $sql = 'SELECT * FROM ';
                $sql .= 'INFORMATION_SCHEMA.COLUMNS ';
                $sql .= 'WHERE ';
                $sql .= "table_name = '" . $value[ $tablesKey ] . "' AND table_schema = '$database'";
                $rs2 = $con->query($sql);
                foreach ($rs2 as $key2 => $value2) {
                    $temp['COLUMN'][] = $value2;
                }
                $tables[$temp['func']] = $temp;
            }
            return $tables;
        },3600*24*7);
        //菜单
        $tree = ['sql' =>['name'=>'数据表','data'=>$tables]];

        $this->assign('tables',$tables);
        $this->assign('tree',$tree);
        return $this->fetch('data');
    }

    public function getTable($table = '') {

        $table = input('param.table',$table);
        if($table) {
            $cache = cache('manual_tabels');
            //多表
            $tables = explode(',',$table);
            $prefix = config('database.prefix');
            foreach ($tables AS $t) {
                if(!StrFind($t,$prefix)) {
                    $t = $prefix.$t;
                }
                $field[$t] = array_column($cache[$t]['COLUMN'],NULL,'COLUMN_NAME');
            }
            return $field;
        }

    }

    public function  refreshData() {
        Cache::rm('manual_tabels');
        return 1;
    }

}
